package com.atguigu.gmall.item.controller;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author lfy
 * @Description
 * @create 2023-07-18 14:06
 */
@RestController
public class IncrController {



    @Autowired
    StringRedisTemplate redisTemplate;

//    ReentrantLock lock = new ReentrantLock();
    @Autowired
    MyDistLock lockxxxxx;

    @Autowired
    RedissonClient redisson;


    /**
     * redisson锁特性
     * 1、所有操作都是原子的
     * 2、lock() 阻塞式加锁；加锁可以自动续期，默认是 30s的锁时间
     * 3、lock(传入解锁时间) 阻塞式加锁： 锁时间就是指定的时间且不会自动续期
     * 4、tryLock()： 尝试加锁，试一下会返回成功或失败。 ；加锁可以自动续期.默认是 30s的锁时间
     * 5、tryLock(10,TimeUnit.SECONDS); 等待指定的时间如果都没有获取到锁就返回false；
     * 6、tryLock(10,20,TimeUnit.SECONDS); 最多在10s内进行尝试加锁，加到以后锁时间为20s，且不可续期
     *
     * =====结论： 传入锁时间的，不会有自动续期功能；锁名只要一样就是同一把锁
     *
     * 7、unlock() 是安全的不会解掉别人的锁
     * @return
     *
     * 核心原理
     * 1、怎么加锁?
     * 2、锁的默认时间怎么来？
     * 3、锁怎么续期？
     */
    @GetMapping("/incr/test")
    public String incr() throws InterruptedException {

        //1、获取一把锁
        RLock lock = redisson.getLock("lock");

        //2、加锁
        lock.lock(); //阻塞式加锁
//        lock.lock(20,TimeUnit.SECONDS);
        //业务 +1
        //1、读值
        String incr = redisTemplate.opsForValue().get("incr");
        //2、+1
        Integer value = Integer.valueOf(incr);
        value += 1;
        //3、写值
        redisTemplate.opsForValue().set("incr",value+"");
        TimeUnit.SECONDS.sleep(50);


        lock.unlock();




        return "ok";
    }

}
